/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.meteocal.gui;

import it.polimi.meteocal.entities.Event;
import it.polimi.meteocal.entities.Invitation;
import it.polimi.meteocal.entities.Notification;
import it.polimi.meteocal.entities.User;
import it.polimi.meteocal.sessionbeans.EventManager;
import it.polimi.meteocal.sessionbeans.NotificationManager;
import it.polimi.meteocal.sessionbeans.UserManager;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import org.apache.commons.lang3.time.DateUtils;
import org.primefaces.context.RequestContext;
import org.primefaces.model.DefaultScheduleEvent;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.primefaces.model.ScheduleEvent;

@ManagedBean(name = "NotificationBean")
// SCOPE
@SessionScoped
public class NotificationBean implements Serializable {
    
    @EJB
    NotificationManager nm;
    
    @EJB
    EventManager em;
    
    @EJB
    UserManager um;
       
    private List<Notification> notifications;
    private Notification selectedNotification;
    
    @ManagedProperty(value="#{ScheduleView}")
    private ScheduleView sv;
    
    public NotificationBean() {
    }
    
    public ScheduleView getSv(){
        return this.sv;
    }
    
    public void setSv(ScheduleView sv){
        this.sv = sv;
    }
    
    public List<Notification> getNotifications(){  
        this.notifications = nm.getNotifications();
        return this.notifications;
    }
    
    public void setNotifications(List<Notification> n){
        this.notifications = n;
    }
    
    public Notification getSelectedNotification(){
        return this.selectedNotification;
    }
    
    public void setSelectedNotification(Notification n){
        this.selectedNotification = n;
        RequestContext context = RequestContext.getCurrentInstance();
        if(this.selectedNotification.getType().equals("invitation"))
            context.execute("PF('invitationDialog').show()");       
        else if(this.selectedNotification.getType().equals("modification"))
                context.execute("PF('modificationDialog').show()");
        else if(this.selectedNotification.getType().equals("deletion"))
                context.execute("PF('deletionDialog').show()");
        else if(this.selectedNotification.getType().equals("newdayproposal"))
                context.execute("PF('newdayDialog').show()");
        else if(this.selectedNotification.getType().equals("badweather"))
                context.execute("PF('badweatherDialog').show()");
    }
    
    public void acceptInvitation(/*ActionEvent actionEvent*/){
        Event e;
        if(this.selectedNotification != null){
            e = this.selectedNotification.getEventID();
            /* Set true il campo di partecipazione all'evento */
            nm.setParticipation(e, true);
            
            /* Aggiunge l'evento al calendario */
            sv.getEventModel()
              .addEvent(new DefaultScheduleEvent(e.getName(), e.getStartHour(), e.getEndHour()));
        }        
    }
    
    public void declineInvitation(ActionEvent actionEvent){
        Event myEvent;
        if(this.selectedNotification != null){
            /* Set false il campo di partecipazione all'evento */
            myEvent = this.selectedNotification.getEventID();
            nm.setParticipation(myEvent, false);
        }
    }
    
    public boolean alreadyAccepted(){
        User u = um.getLoggedUser();
        Event e;
        boolean result = false;
        if(this.selectedNotification != null){
            e = this.selectedNotification.getEventID();        
            for(Invitation i : u.getInvitationList()){
                if(i.getEvent().equals(e) && i.getParticipant() == true){
                    result = true;
                    break;
                }
            }
        }
        return result;       
    }
    
    public boolean alreadyDeclined(){
        User u = um.getLoggedUser();
        Event e;
        boolean result = false;
        if(this.selectedNotification != null){ 
            e = this.selectedNotification.getEventID();
            for(Invitation i : u.getInvitationList()){
                if(i.getEvent().equals(e) && i.getParticipant() == false &&
                    i.getAcceptDate()!= null){
                    result = true;
                    break;
                }
            }       
        }
        return result;
    }
    
    public boolean alreadyDecided(){
        User u = um.getLoggedUser();
        Event e;
        boolean result = false;
        if(this.selectedNotification != null){
            e = this.selectedNotification.getEventID();
            for(Invitation i : u.getInvitationList()){
                if(i.getEvent().equals(e) && i.getAcceptDate() != null){
                    result = true;
                    break;
                }
            }
        }
        return result;       
    }
    
    public String checkParticipation(User u){
        String result = "";
        um.refreshUser(u);
        for(Invitation i : u.getInvitationList()){
            if(i.getEvent().equals(this.selectedNotification.getEventID())){
                if(i.getParticipant() == true){result = "accepted"; return result;}
                else if(i.getAcceptDate() != null) {result = "declined"; return result;}
                else {result = "pending"; return result;}                      
            }        
        }
        return result;
    }
    
    public void changeEventDates(){
        /* Cambio date di inizio e fine dell'evento e salvo su DB */
        Event e = this.selectedNotification.getEventID();
        Date eventStartDate = e.getStartHour();
        Date proposedStartDate = this.selectedNotification.getProposedDate();
        int dayDifference = Days.daysBetween(new DateTime(eventStartDate), new DateTime(proposedStartDate)).getDays();
        Date eventEndDate = e.getEndHour();
        Date newEndDate = DateUtils.addDays(eventEndDate, dayDifference);
                
        e.setStartHour(proposedStartDate);
        e.setEndHour(newEndDate);
        em.saveModifiedEvent(e);
        
        /* Inserisco nel DB una notifica di modifica dell'evento */
        nm.sendModificationNotification(e);
        
        /* Mostro l'evento modificato nel calendario */
        List<ScheduleEvent> allEvents = sv.getEventModel().getEvents();
        ScheduleEvent newSe = null;
        for(ScheduleEvent se : allEvents){
            if(se.getTitle().equals(e.getName()) && 
               se.getStartDate().equals(eventStartDate) && 
               se.getEndDate().equals(eventEndDate)){
                sv.getEventModel().deleteEvent(se);
                newSe = new DefaultScheduleEvent(e.getName(), proposedStartDate, newEndDate);
                sv.getEventModel().addEvent(newSe);
                break;              
            }
        }
        
    }
    
}
